<?php

if(!defined('IN_SYS')) exit('Access Denied');

class session
{
	private $max_life_time  = 1800;

	private $session_name   = 'ssid';
	private $session_id     = '';

	private $session_expiry = '';
	private $session_md5    = '';

	private $session_cookie_path   = '/';
	private $session_cookie_domain = '';

	private $_ip   = '';
	private $_time = 0;

	public function __construct(){

		$GLOBALS['_SESSION'] = array();

		$this->_ip = get_client_ip();
		$this->_time = time();

		if (!empty($_COOKIE[$this->session_name]) || !empty($_GET[$this->session_name])){
			$tmp_session_id = isset($_COOKIE[$this->session_name])?addslashes($_COOKIE[$this->session_name]):addslashes($_GET[$this->session_name]);
			$sess_id = substr($tmp_session_id, 0, 32);
			if ($this->create_session_key($sess_id) == substr($tmp_session_id, 32)){
				$this->session_id = $sess_id;
			}
		}

		if ($this->session_id){
			$this->load_session();
		}else{
			$this->create_session_id();
			setcookie($this->session_name, $this->session_id . $this->create_session_key($this->session_id), 0, $this->session_cookie_path, $this->session_cookie_domain, false);
		}

		register_shutdown_function(array(&$this, 'close_session'));
	}

	public function create_session_id(){
		$this->session_id = md5(uniqid(mt_rand(), true));
		return $this->insert_session();
	}

	public function create_session_key($session_id){
		$user_agent = !empty($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
		return sprintf('%08x', crc32( $user_agent . $session_id ));
	}

	public function insert_session(){
		return db::query("INSERT INTO sessions (session_id, expiry, ip, data) VALUES ('" . $this->session_id . "', '". $this->_time ."', '". $this->_ip ."', 'a:0:{}')");
	}

	public function load_session(){
		global $auth_key;
		$session = db::find("SELECT data, expiry FROM sessions WHERE session_id = '" . $this->session_id . "'");
		if (empty($session)){
			$this->insert_session();
			$this->session_expiry = 0;
			$this->session_md5    = '807a1227336511726a75516e921156c4';
			$GLOBALS['_SESSION']  = array();
		}else{
			$this->session_md5    = md5($auth_key.$session['data']);
			$this->session_expiry = $session['expiry'];

			if($this->_time - $session['expiry'] <= $this->max_life_time){
				if (!empty($session['data'])){
					$GLOBALS['_SESSION']  = unserialize($session['data']);
				}
			}
		}
	}

	public function update_session(){
		global $auth_key;
		$data = serialize($GLOBALS['_SESSION']);
		if ($this->session_md5 == md5($auth_key.$data) && $this->_time < $this->session_expiry + 60){
			return true;
		}
		$data = addslashes($data);
		return db::query("UPDATE sessions SET expiry = '" . $this->_time . "', data = '$data' WHERE session_id = '" . $this->session_id . "'");
	}

	public function close_session(){
		$this->update_session();
		if (($this->_time % 10) == 0){
			db::query('delete FROM sessions WHERE expiry < ' . ($this->_time - $this->max_life_time));
		}
		return true;
	}
}

?>